package com.zsc.oj.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zsc.oj.annotation.AuthCheck;
import com.zsc.oj.common.BaseResponse;
import com.zsc.oj.common.DeleteRequest;
import com.zsc.oj.common.ErrorCode;
import com.zsc.oj.common.ResultUtils;
import com.zsc.oj.constant.PostThumbRedisConstant;
import com.zsc.oj.constant.UserConstant;
import com.zsc.oj.exception.BusinessException;
import com.zsc.oj.exception.ThrowUtils;
import com.zsc.oj.model.dto.postThumb.*;
import com.zsc.oj.model.entity.PostThumb;
import com.zsc.oj.model.entity.User;
import com.zsc.oj.model.vo.PostThumbVO;
import com.zsc.oj.service.PostThumbService;
import com.zsc.oj.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RSet;
import org.redisson.api.RedissonClient;
import org.springframework.beans.BeanUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.sql.Wrapper;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 帖子点赞接口
 *
 * @author <a href="https://github.com/liyupi">程序员鱼皮</a>
 * @from <a href="https://www.code-nav.cn">编程导航学习圈</a>
 */
@RestController
@RequestMapping("/postThumb")
@Slf4j
public class PostThumbController {

    @Resource
    private PostThumbService postThumbService;

    @Resource
    private UserService userService;

    @Resource
    private RedissonClient redissonClient;

    // region 增删改查

    /**
     * 创建帖子点赞
     *
     * @param postThumbAddRequest
     * @param request
     * @return
     */
    @PostMapping("/add")
    public BaseResponse<Boolean> addPostThumb(@RequestBody PostThumbAddRequest postThumbAddRequest, HttpServletRequest request) {
        ThrowUtils.throwIf(postThumbAddRequest == null, ErrorCode.PARAMS_ERROR);
        // todo 在此处将实体类和 DTO 进行转换
        PostThumb postThumb = new PostThumb();
        BeanUtils.copyProperties(postThumbAddRequest, postThumb);
        // 数据校验
        postThumbService.validPostThumb(postThumb, true);
        // todo 填充默认值
        User loginUser = userService.getLoginUser(request);
        postThumb.setUserId(loginUser.getId());

        boolean result = postThumbService.addPostThumb(postThumbAddRequest);

        return ResultUtils.success(result);
    }

    /**
     * 删除帖子点赞
     *
     * @param postThumbDeleteRequest
     * @param request
     * @return
     */
    @PostMapping("/delete")
    public BaseResponse<Boolean> deletePostThumb(@RequestBody PostThumbDeleteRequest postThumbDeleteRequest, HttpServletRequest request) {
        if (postThumbDeleteRequest == null || postThumbDeleteRequest.getPostId() <= 0 || postThumbDeleteRequest.getUserId() <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }

        boolean result = postThumbService.deletePosThumb(postThumbDeleteRequest,request);

        return ResultUtils.success(result);
    }

    /**
     * 更新帖子点赞（仅管理员可用）
     *
     * @param postThumbUpdateRequest
     * @return
     */
    @PostMapping("/update")
    @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
    public BaseResponse<Boolean> updatePostThumb(@RequestBody PostThumbUpdateRequest postThumbUpdateRequest) {
        if (postThumbUpdateRequest == null || postThumbUpdateRequest.getId() <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        // todo 在此处将实体类和 DTO 进行转换
        PostThumb postThumb = new PostThumb();
        BeanUtils.copyProperties(postThumbUpdateRequest, postThumb);
        // 数据校验
        postThumbService.validPostThumb(postThumb, false);
        // 判断是否存在
        long id = postThumbUpdateRequest.getId();
        PostThumb oldPostThumb = postThumbService.getById(id);
        ThrowUtils.throwIf(oldPostThumb == null, ErrorCode.NOT_FOUND_ERROR);
        // 操作数据库
        boolean result = postThumbService.updateById(postThumb);
        ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR);
        return ResultUtils.success(true);
    }

    /**
     * 根据 id 获取帖子点赞（封装类）
     *
     * @param id
     * @return
     */
    @GetMapping("/get/vo")
    public BaseResponse<PostThumbVO> getPostThumbVOById(long id, HttpServletRequest request) {
        ThrowUtils.throwIf(id <= 0, ErrorCode.PARAMS_ERROR);
        // 查询数据库
        PostThumb postThumb = postThumbService.getById(id);
        ThrowUtils.throwIf(postThumb == null, ErrorCode.NOT_FOUND_ERROR);
        // 获取封装类
        return ResultUtils.success(postThumbService.getPostThumbVO(postThumb, request));
    }

    /**
     * 分页获取帖子点赞列表（仅管理员可用）
     *
     * @param postThumbQueryRequest
     * @return
     */
    @PostMapping("/list/page")
    @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
    public BaseResponse<Page<PostThumb>> listPostThumbByPage(@RequestBody PostThumbQueryRequest postThumbQueryRequest) {
        long current = postThumbQueryRequest.getCurrent();
        long size = postThumbQueryRequest.getPageSize();
        // 查询数据库
        Page<PostThumb> postThumbPage = postThumbService.page(new Page<>(current, size),
                postThumbService.getQueryWrapper(postThumbQueryRequest));
        return ResultUtils.success(postThumbPage);
    }

    /**
     * 分页获取帖子点赞列表（封装类）
     *
     * @param request
     * @return
     */
    @PostMapping("/list/page/vo")
    public BaseResponse<List<Long>> listPostThumbVOByPage(@RequestBody HttpServletRequest request) {
        User loginUser = userService.getLoginUser(request);
        QueryWrapper<PostThumb> postThumbQueryWrapper = new QueryWrapper<>();
        postThumbQueryWrapper.eq("userId",loginUser.getId());
        List<PostThumb> postThumbList = postThumbService.list(postThumbQueryWrapper);
        List<Long> postIdList = postThumbList.stream().map(PostThumb::getPostId).collect(Collectors.toList());
        return ResultUtils.success(postIdList);
    }

    /**
     * 分页获取当前登录用户创建的帖子点赞列表
     *
     * @param postThumbQueryRequest
     * @param request
     * @return
     */
    @PostMapping("/my/list/page/vo")
    public BaseResponse<Page<PostThumbVO>> listMyPostThumbVOByPage(@RequestBody PostThumbQueryRequest postThumbQueryRequest,
                                                                 HttpServletRequest request) {
        ThrowUtils.throwIf(postThumbQueryRequest == null, ErrorCode.PARAMS_ERROR);
        // 补充查询条件，只查询当前登录用户的数据
        User loginUser = userService.getLoginUser(request);
        postThumbQueryRequest.setUserId(loginUser.getId());
        long current = postThumbQueryRequest.getCurrent();
        long size = postThumbQueryRequest.getPageSize();
        // 限制爬虫
        ThrowUtils.throwIf(size > 20, ErrorCode.PARAMS_ERROR);
        // 查询数据库
        Page<PostThumb> postThumbPage = postThumbService.page(new Page<>(current, size),
                postThumbService.getQueryWrapper(postThumbQueryRequest));
        // 获取封装类
        return ResultUtils.success(postThumbService.getPostThumbVOPage(postThumbPage, request));
    }

    /**
     * 编辑帖子点赞（给用户使用）
     *
     * @param postThumbEditRequest
     * @param request
     * @return
     */
    @PostMapping("/edit")
    public BaseResponse<Boolean> editPostThumb(@RequestBody PostThumbEditRequest postThumbEditRequest, HttpServletRequest request) {
        if (postThumbEditRequest == null || postThumbEditRequest.getId() <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        // todo 在此处将实体类和 DTO 进行转换
        PostThumb postThumb = new PostThumb();
        BeanUtils.copyProperties(postThumbEditRequest, postThumb);
        // 数据校验
        postThumbService.validPostThumb(postThumb, false);
        User loginUser = userService.getLoginUser(request);
        // 判断是否存在
        long id = postThumbEditRequest.getId();
        PostThumb oldPostThumb = postThumbService.getById(id);
        ThrowUtils.throwIf(oldPostThumb == null, ErrorCode.NOT_FOUND_ERROR);
        // 仅本人或管理员可编辑
        if (!oldPostThumb.getUserId().equals(loginUser.getId()) && !userService.isAdmin(loginUser)) {
            throw new BusinessException(ErrorCode.NO_AUTH_ERROR);
        }
        // 操作数据库
        boolean result = postThumbService.updateById(postThumb);
        ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR);
        return ResultUtils.success(true);
    }

    // endregion
}
